using Headspring.Training.Core.Model;
using Headspring.Training.Core.Model.StateCommands;
using Headspring.Training.Core.Services;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using Rhino.Mocks;

namespace Headspring.Training.UnitTests.Model.StateCommands
{
	[TestFixture]
	public class CompleteToCancelledCommandTester
	{
		[Test]
		public void ShouldBeValid()
		{
			var order = new WorkOrder {Status = WorkOrderStatus.Complete};
			var employee = new Employee();
			order.Creator = employee;

			var command = new CompleteToCancelledCommand(order, employee);
			Assert.That(command.IsValid(), Is.True);
		}

		[Test]
		public void ShouldNotBeValidInWrongStatus()
		{
			var order = new WorkOrder {Status = WorkOrderStatus.Draft};
			var employee = new Employee();
			order.Creator = employee;

			var command = new CompleteToCancelledCommand(order, employee);
			Assert.That(command.IsValid(), Is.False);
		}

		[Test]
		public void ShouldNotBeValidWithWrongEmployee()
		{
			var order = new WorkOrder {Status = WorkOrderStatus.Complete};
			var employee = new Employee();
			order.Assignee = employee;

			var command = new CompleteToCancelledCommand(order, employee);
			Assert.That(command.IsValid(), Is.False);
		}

		[Test]
		public void ShouldShowCorrectVerb()
		{
			var order = new WorkOrder {Status = WorkOrderStatus.Cancelled};
			var command = new CompleteToCancelledCommand(order, new Employee());

			Assert.AreEqual("Cancel", command.TransitionVerbPresentTense);
			Assert.AreEqual("Cancelled", command.TransitionVerbPastTense);
		}

		[Test]
		public void ShouldTransitionStateProperly()
		{
			if (WorkOrderStatus.Complete != null)
			{
				var order = new WorkOrder
				            	{Number = "123", Status = WorkOrderStatus.Complete};
				var employee = new Employee();
				order.Creator = employee;

				var commandVisitor = MockRepository.GenerateMock<IStateCommandVisitor>();
				commandVisitor.Expect(visitor => visitor.SaveWorkOrder(order));
				commandVisitor.Expect(
					visitor => visitor.SendMessage("You have cancelled work order 123"));
				commandVisitor.Expect(visitor => visitor.EditWorkOrder(order));

				var command = new CompleteToCancelledCommand(order, employee);
				command.Execute(commandVisitor);

				commandVisitor.VerifyAllExpectations();
				Assert.That(order.Status, Is.EqualTo(WorkOrderStatus.Cancelled));
			}
		}
	}
}